<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- 1、写模板 -->
   <div id="root">
     <h1>{{name}}</h1>
     <h2>{{msg}}</h2>
   </div>
   <script>
    let reg = /\{\{(.+?)\}\}/g
    // 1、拿到模板
    const tmpNode = document.querySelector('#root');
    // 2、拿到数据
    let data = {
      name: '张三',
      msg: 'hello world'
    }
    // 3、将数据与模板结合，得到html（DOM元素）
    /* 
     1、一般使用递归、正则
     2、此案例的 template 是 DOM 元素
     3、在真正的 Vue 原码中是 DOM -》字符串模板-》ast-》VNode-》真实 DOM
    */
   function compiler(template, data) {
    let childNodes = template.childNodes
    for(let i= 0; i < childNodes.length; i++) {
      let type = childNodes[i].nodeType // 1 元素，3 文本
      if(type === 3) {
        // 文本节点，判断里面是否有 {{}} 插值
        let txt = childNodes[i].nodeValue // 该属性只有文本节点才有意义

        // 判断 text 是否有 {{}}，使用正则
        txt = txt.replace(reg, function(_, g) {
          /* 
          replace 使用一次正则，函数就会调用一次，_ 是匹配到的带{{}}的值，g 是{{}} 里面的值
          */
          let key = g.trim() // 去掉空格，获取真正 data 的 key 值
          let value = data[key]
          // 将文本节点中的 {{}} 替换成获取到的值
          return value
        })
        
        // txt 现在和 DOM 元素没有关系，需要进行下面的操作
        childNodes[i].nodeValue = txt // 将处理后的文本节点替换到原来的文本节点位置
      } else if(type === 1) {
        // 元素节点，判断是否有子元素，是否要递归，判断是否要插值
        compiler(childNodes[i], data)
      }
    }
   }
   console.log(tmpNode);
   let generaNode = tmpNode.cloneNode(true) // 拷贝一份，不操作原来的 DOM 元素，不然坑位会被占据（引用类型），导致响应式失效
   compiler(generaNode, data)
   console.log(generaNode);
   
   // 4、渲染到页面
   root.parentNode.replaceChild(generaNode, root)

   /* 
    简易版实例，存在问题：
    1、Vue 使用的 虚拟 DOM，案例是真实 DOM
    2、只考虑了单属性（{{name}}）， 而没有解决（{{name.firstName.lastName}}） 多属性的问题
    3、代码没有整合，只是把功能拆分出来
   */
   </script>
</body>
</html>